#ifndef D67D662C_AC28_4C38_B51A_BA9F6D1817CF
#define D67D662C_AC28_4C38_B51A_BA9F6D1817CF

#include "usbd_customhid.h"

#define CMD_QUEUE_NUM   5
#define USB_PORT_SIZE CUSTOM_HID_EPOUT_SIZE
#define BUFF_SIZE USB_PORT_SIZE-5


enum CommCmd
{
    COMM_UART = 1,
    COMM_ADC,
    COMM_IIC_MASTER,
    COMM_IIC_SLAVE,
    COMM_SPI_MASTER,
    COMM_SPI_SLAVE,
    COMM_GPIO,
    COMM_PWM,
    COMM_UPDATE,
};
enum CommSubCmdUart
{
    COMM_SUB_UART_SET_PARAM = 1,
    COMM_SUB_UART_SEND,
    COMM_SUB_UART_REC
};

enum CommSubCmdADC
{
    COMM_SUB_ADC_UPDATE = 1,
};

enum CommSubCmdIICMaster
{
    COMM_SUB_IIC_MASTER_SET_PARAM = 1,
    COMM_SUB_IIC_MASTER_WRITE,
    COMM_SUB_IIC_MASTER_READ
};

enum CommSubCmdSPIMaster
{
    COMM_SUB_SPI_MASTER_SET_PARAM = 1,
    COMM_SUB_SPI_MASTER_WRITE,
    COMM_SUB_SPI_MASTER_READ,
    COMM_SUB_SPI_MASTER_WRITE_READ,
};

enum CommSubCmdSPSLAVE
{
    COMM_SUB_SPI_SLAVE_SET_PARAM = 1,
    COMM_SUB_SPI_SLAVE_WRITE,
    COMM_SUB_SPI_SLAVE_READ,
    COMM_SUB_SPI_SLAVE_WRITE_READ,
};

enum CommSubCmdIICSlave
{
    COMM_SUB_IIC_SLAVE_SET_PARAM = 1,
    COMM_SUB_IIC_SLAVE_WRITE,
    COMM_SUB_IIC_SLAVE_READ
};

enum CommSubGPIO
{
    COMM_SUB_GPIO_PIN_SET = 1,
    COMM_SUB_GPIO_HL_CHANGE,
    COMM_SUB_GPIO_LEVEL_SET,
    COMM_SUB_GPIO_LEVEL_READ,
};

enum CommSubPWM
{
    COMM_SUB_PWM_SET_PARAM = 1,
    COMM_SUB_PWM_OPEN_CLOSE,
};

enum CommSubUpdate
{
    COMM_SUB_UPDATE_BEGIN = 1,
    COMM_SUB_UPDATE_DATA_SEND,
    COMM_SUB_UPDATE_STOP,
    COMM_SUB_UPDATE_VERSION
};

#define COM_OK      0
#define COM_FAIL    1
#define COM_TIMEOUT 2
#define COM_MEM     3
#define COM_MODE    4
#define COM_STOP    5

typedef struct SendCmd
{
    unsigned char cmd;
    unsigned char subCmd;
    void (*sendDeal)(unsigned char cmd, unsigned char subCmd, void *param);
} SendCmd;

typedef struct RecCmd
{
    unsigned char cmd;
    unsigned char subCmd;
    void (*recDeal)(unsigned char cmd, unsigned char subCmd, unsigned char *data);
} RecCmd;

typedef struct UsbCmd
{
    unsigned char cmd;
    unsigned char subCmd;
    void *param;
} UsbCmd;


void usb_init(void);
void usb_loop(void);
char usb_cmd(unsigned char cmd, unsigned char subCmd, void *param);
void usb_send(unsigned char *arr, unsigned short len);
void usb_rec(unsigned char *arr, unsigned short len);
void usb_reply_ok(unsigned char cmd, unsigned char subCmd, void *ok);
unsigned char chksum(unsigned char *b, int len);
void delay_us(unsigned long time);
#endif /* D67D662C_AC28_4C38_B51A_BA9F6D1817CF */
